#include "stusql.h"                // 包含 stuSql 类的头文件定义
#include <QMessageBox>             // 包含用于显示消息框的类
#include <QSqlDatabase>            // 包含用于管理数据库连接的类
#include <QSqlError>               // 包含用于处理 SQL 错误的类
#include <QSqlQuery>               // 包含用于执行 SQL 查询的类
#include <QDebug>                  // 包含用于调试输出的类
#include <QCoreApplication>        // 包含用于访问应用程序目录等信息的类
#include <QTime>
#include <QDir>
#include"admsql.h"
// 静态成员变量初始化
stuSql *stuSql::ptrStuSql = nullptr;

stuSql* stuSql::getInstance()
{
    if (ptrStuSql == nullptr) {
        ptrStuSql = new stuSql();
    }
    return ptrStuSql;
}
// 构造函数：初始化时调用，设置父对象并调用 init() 方法。
stuSql::stuSql(QObject *parent)
    : QObject{parent}              // 初始化基类 QObject，传递父对象指针
{
    qDebug() << "Creating stuSql instance at:" << QTime::currentTime().toString("hh:mm:ss.zzz");
}

void stuSql::init(){
    AdmSql sql;
    sql.init();
}

// 获取学生总数的方法
quint32 stuSql::getStuCnt()
{
    QSqlQuery sql(m_db);                                       // 创建一个 QSqlQuery 对象，关联到 m_db 数据库连接
    sql.exec("select count(id) from student;");                // 执行 SQL 查询，统计 student 表中记录数
    quint32 cnt = 0;                                           // 初始化计数器变量
    while (sql.next()) {                                       // 遍历查询结果集
        qDebug() << sql.value(0).toUInt();                     // 输出查询结果（调试信息）
        cnt = sql.value(0).toUInt();                           // 将查询结果转换为无符号整数并赋值给 cnt
    }
    return cnt;                                                // 返回学生总数
}

// 获取分页学生数据的方法
QList<StuInfo> stuSql::getPageStu(quint32 page, quint32 cnt)
{
    QList<StuInfo> l;                                          // 定义一个 StuInfo 结构体列表，用于存储查询结果
    QSqlQuery sql(m_db);                                       // 创建一个 QSqlQuery 对象，关联到 m_db 数据库连接
    QString strsql = QString("select * from student order by id limit %1 offset %2;")
                         .arg(cnt).arg(page * cnt);                // 构建 SQL 查询字符串，实现分页查询
    // QString strsql = QString("SELECT * FROM student ORDER BY age ASC LIMIT %1 OFFSET %2;")
    //                      .arg(cnt).arg(page * cnt);
    sql.exec(strsql);                                          // 执行构建好的 SQL 查询
    StuInfo info;                                              // 定义一个 StuInfo 结构体实例，用于临时存储每一行数据
    while (sql.next()) {                                       // 遍历查询结果集
        info.id = sql.value(0).toUInt();                       // 将查询结果的第一列（id）转换为无符号整数并赋值给 info.id
        info.sid = sql.value(1).toString();                    // 将查询结果的第二列（sid）转换为字符串并赋值给 info.sid
        info.sname = sql.value(2).toString();                  // 将查询结果的第三列（sname）转换为字符串并赋值给 info.sname
        info.age = sql.value(3).toUInt();                      // 将查询结果的第四列（age）转换为无符号整数并赋值给 info.age
        info.grade = sql.value(4).toUInt();                    // 将查询结果的第五列（grade）转换为无符号整数并赋值给 info.grade
        info.sclass = sql.value(5).toUInt();                   // 将查询结果的第六列（sclass）转换为无符号整数并赋值给 info.sclass
        info.phone = sql.value(6).toString();                  // 将查询结果的第七列（phone）转换为字符串并赋值给 info.phone
        l.push_back(info);                                     // 将构造好的 StuInfo 实例添加到列表中
    }
    return l;                                                  // 返回包含分页学
}
bool stuSql::addStu(StuInfo info)
{
    QSqlQuery sql(m_db);                                       // 创建一个 QSqlQuery 对象，关联到 m_db 数据库连接
    QString strSql = QString("INSERT INTO student VALUES (null,'%1', '%2', %3, %4, %5, '%6')")
                         .arg(info.sid).arg(info.sname).arg(info.age).arg(info.grade).arg(info.sclass).arg(info.phone);
    bool ret = sql.exec(strSql);
    qDebug() << "Adding student:" << info.sname << "Success:" << ret; // 添加调试信息
    return ret;                                                // 返回操作是否成功的布尔值
}

// 删除学生记录的方法
bool stuSql::delStu(int id)
{
    QSqlQuery sql(m_db);                                       // 创建一个 QSqlQuery 对象，关联到 m_db 数据库连接
    return sql.exec(QString("delete from student where id = %1").arg(id)); // 执行删除操作，并返回操作是否成功的布尔值
}

// 清空所有学生记录的方法
bool stuSql::clearStu()
{
    QSqlQuery sql(m_db);                                       // 创建一个 QSqlQuery 对象，关联到 m_db 数据库连接
    return sql.exec(QString("delete from student"));           // 执行清空操作，并返回操作是否成功的布尔值
}

// 更新学生记录的方法
bool stuSql::updateStu(StuInfo info)
{
    QSqlQuery sql(m_db);                                       // 创建一个 QSqlQuery 对象，关联到 m_db 数据库连接
    QString strSql = QString("update student set sid='%1',sname='%2',age=%3,grade=%4,class=%5,phone='%6' where id=%7")
                         .arg(info.sid).arg(info.sname).arg(info.age).arg(info.grade).arg(info.sclass).arg(info.phone).arg(info.id);
    qDebug() << strSql;
    bool ret = sql.exec(strSql);                               // 执行更新操作，并保存结果到 ret 变量
    QSqlError e = sql.lastError();                             // 获取最后一次执行的 SQL 错误信息
    if (e.isValid()) {                                         // 如果有有效的错误信息
        qDebug() << e.text();                                  // 打印错误信息（调试信息）
    }
    return ret;                                                // 返回操作是否成功的布尔值
}

QVector<StuInfo> stuSql::searchStu(const QString &condition, bool isSidSearch)
{
    QSqlQuery query(m_db);
    QString strSql;
    QVector<StuInfo> results;

    // 构建 SQL 查询语句
    if (isSidSearch) {
        strSql = QString("SELECT * FROM student WHERE sid='%1'").arg(condition);
    } else {
        strSql = QString("SELECT * FROM student WHERE sname LIKE '%%1%'").arg(condition);
    }

    qDebug() << "Executing SQL:" << strSql;

    // 执行查询操作
    if (!query.exec(strSql)) {
        qDebug() << "SQL Error:" << query.lastError().text();
        return results; // 返回空的结果集
    }

    while (query.next()) {
        StuInfo info;
        info.id = query.value("id").toUInt();
        info.sid = query.value("sid").toString();
        info.sname = query.value("sname").toString();
        info.age = query.value("age").toUInt();
        info.grade = query.value("grade").toUInt();
        info.sclass = query.value("class").toUInt();
        info.phone = query.value("phone").toString();

        results.append(info);
    }

    return results;
}
QList<StuInfo> stuSql::getSortStu(quint32 page, quint32 cnt, const QString& customQuery)
{
    QList<StuInfo> l;                                          // 定义一个 StuInfo 结构体列表，用于存储查询结果
    QSqlQuery sql(m_db);                                       // 创建一个 QSqlQuery 对象，关联到 m_db 数据库连接

    // 如果提供了自定义查询，则使用它；否则使用默认查询
    if (!customQuery.isEmpty()) {
        sql.exec(customQuery);
    } else {
        QString strsql = QString("SELECT * FROM student ORDER BY age ASC LIMIT %1 OFFSET %2;")
        .arg(cnt).arg(page * cnt);
        sql.exec(strsql);
    }

    StuInfo info;                                              // 定义一个 StuInfo 结构体实例，用于临时存储每一行数据
    while (sql.next()) {                                       // 遍历查询结果集
        info.id = sql.value(0).toUInt();                       // 将查询结果的第一列（id）转换为无符号整数并赋值给 info.id
        info.sid = sql.value(1).toString();                    // 将查询结果的第二列（sid）转换为字符串并赋值给 info.sid
        info.sname = sql.value(2).toString();                  // 将查询结果的第三列（sname）转换为字符串并赋值给 info.sname
        info.age = sql.value(3).toUInt();                      // 将查询结果的第四列（age）转换为无符号整数并赋值给 info.age
        info.grade = sql.value(4).toUInt();                    // 将查询结果的第五列（grade）转换为无符号整数并赋值给 info.grade
        info.sclass = sql.value(5).toUInt();                   // 将查询结果的第六列（sclass）转换为无符号整数并赋值给 info.sclass
        info.phone = sql.value(6).toString();                  // 将查询结果的第七列（phone）转换为字符串并赋值给 info.phone
        l.push_back(info);                                     // 将构造好的 StuInfo 实例添加到列表中
    }
    return l;                                                  // 返回包含分页学生数据的列表
}

